#include "PrototypeTool.h"
#include "Acceptor.h"
#include "DiagramMan.h"
#include "DiagramFam.h"
#include "../model/UMLObject.h"
#include "../view/UMLCanvas.h"

PrototypeTool::PrototypeTool(DiagramMan& dman, const UMLObject& prototype)
:	Tool(dman),
	_prototype(prototype.clone())
	// default for _cmd
	// default for _lastDrag
{
}

PrototypeTool::PrototypeTool(const PrototypeTool& pt)
:	Tool(pt.dman()),
	_prototype(pt._prototype->clone()),
	_cmd(pt._cmd.get() ? new PlaceCommand(*pt._cmd) : NULL),
	_lastDrag(pt._lastDrag)
{
}

PrototypeTool& PrototypeTool::operator=(const PrototypeTool& pt)
{
	if (&pt != this)
	{
		/* Clone the prototype, if it exists. */
		_prototype.reset(pt._prototype.get() ? pt._prototype->clone() : NULL);

		_cmd.reset(pt._cmd.get() ? new PlaceCommand(*pt._cmd) : NULL);
		_lastDrag = pt._lastDrag;
	}

	return *this;
}

void PrototypeTool::click(QMouseEvent& ev)
{
	DiagramFam& active = dman().active();

	std::auto_ptr<PlaceCommand> cmd(
			new PlaceCommand(active.diagram(), active.canvas(), *_prototype));

	cmd->prototype().setPosition(tological(ev.pos()));

	active.acceptor().accept(std::auto_ptr<Command>(cmd));
}

void PrototypeTool::startDrag(QPoint& pt)
{
	DiagramFam& active = dman().active();

	_cmd.reset(
			new PlaceCommand(active.diagram(), active.canvas(), *_prototype));

	_lastDrag = tological(pt);
	_cmd->prototype().setPosition(_lastDrag);
}

void PrototypeTool::drag(QMouseEvent& ev)
{
	QPoint logical = tological(ev.pos());

	// no need to send repeat commands
	if (logical != _lastDrag)
	{
		_cmd->prototype().setEnd(logical);

		dman().active().acceptor().acceptTransitive(*_cmd);
		
		_lastDrag = logical;
	}
}

void PrototypeTool::endDrag(QMouseEvent& ev)
{
	using std::auto_ptr;

	_cmd->prototype().setEnd(tological(ev.pos()));

	dman().active().acceptor().accept(auto_ptr<Command>(_cmd));
}

